#include <stdlib.h>
//============================================================================
// Name        : cpp_macaddress.cpp
// Author      : darkflash
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <unistd.h>
#include <iostream>
using namespace std;

int main() {
	 int nSD; // Socket descriptor
	 struct ifreq *ifr; // Interface request
	 struct ifconf ifc;
	 int i, numif;

	 memset(&ifc, 0, sizeof(ifc));
	 ifc.ifc_ifcu.ifcu_req = NULL;
	 ifc.ifc_len = 0;

	 // Create a socket that we can use for all of our ioctls
	 nSD = socket( PF_INET, SOCK_DGRAM, 0 );
	 if ( nSD < 0 ){
		 cout << "socket error!!!" << endl;
		 return 0;
	 }

	 int i_ioctl = ioctl(nSD, SIOCGIFCONF, &ifc);
	 if(i_ioctl < 0){
		 cout << "ioctl error: " << endl;
		 return 0;
	 }
	 if ((ifr = (ifreq*)  malloc(ifc.ifc_len)) == NULL){
		 cout << "malloc error!!!" << endl;
		 return 0;
	 }else{
		 ifc.ifc_ifcu.ifcu_req = ifr;
		 if (ioctl(nSD, SIOCGIFCONF, &ifc) < 0)
		 {
			 cout << "ioctl error!!!" << endl;
			 return 0;
		 }
		 numif = ifc.ifc_len / sizeof(struct ifreq);

		 cout << numif << endl;
		 for (i = 0; i < numif; i++){
			 struct ifreq *r = &ifr[i];
			 struct sockaddr_in *sin = (struct sockaddr_in *)&r->ifr_addr;
			 if (!strcmp(r->ifr_name, "lo")) continue; // skip loopback interface

			 if(ioctl(nSD, SIOCGIFHWADDR, r) < 0) return 0;
			 char macaddr[100];
			 sprintf(macaddr, "[%s] %02X:%02X:%02X:%02X:%02X:%02X",
					 r->ifr_name,
					 (unsigned char)r->ifr_hwaddr.sa_data[0],
					 (unsigned char)r->ifr_hwaddr.sa_data[1],
					 (unsigned char)r->ifr_hwaddr.sa_data[2],
					 (unsigned char)r->ifr_hwaddr.sa_data[3],
					 (unsigned char)r->ifr_hwaddr.sa_data[4],
					 (unsigned char)r->ifr_hwaddr.sa_data[5]);

			 cout << macaddr << endl;
		 }
	 }
	 close(nSD);
	 free(ifr);

	return 0;
}
